﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace QuickFramework.Orm
{
    /// <summary>
    /// 工作单元
    /// </summary>
    public class UnitOfWork : IUnitOfWork,IDisposable
    {
        public UnitOfWork()
        {
            m_ID = Guid.NewGuid().ToString();
        }
        /// <summary>
        /// 创建打开的数据库链接
        /// </summary>
        /// <param name="isMaster"></param>
        /// <returns></returns>
        public IUnitOfWork CreateOpenConnection(string connectionStringName ="Default", bool isMaster = true)
        {
            if (null == m_Connection)
            {
                m_Connection = DbFactory.CreateConnection(connectionStringName, isMaster);
                m_TransactionCount = -1;
            }
            if (m_Connection.State != ConnectionState.Open)
            {
                m_Connection.Open();
            }
            return this;
        }
        /// <summary>
        /// 工作单元链接
        /// </summary>
        IDbConnection m_Connection = null;
        /// <summary>
        /// 工作单元事务
        /// </summary>
        IDbTransaction m_Transaction = null;
        string m_ID;
        /// <summary>
        /// 事务数量,事务数量 = 0 才会进行提交
        /// </summary>
        int m_TransactionCount =0;
        /// <summary>
        /// 工作单元链接
        /// </summary>
        public IDbConnection Connection
        {
            get { return m_Connection; }
        }
        /// <summary>
        /// 工作单元事务
        /// </summary>
        public IDbTransaction Transaction
        {
            get { return m_Transaction; }
        }
        /// <summary>
        /// UnitOfWork ID
        /// </summary>
        public string ID
        {
            get { return m_ID; }
        }
        /// <summary>
        /// 开启事务
        /// </summary>
        public IUnitOfWork BeginTransaction()
        {
            if (null == m_Connection)
            {
                throw new Exception("IDbConnection is null");
            }
            if (m_TransactionCount < 1 && m_Transaction == null)
            {
                m_TransactionCount = 0;
                m_Transaction = m_Connection.BeginTransaction();
            }
            m_TransactionCount++;
            return this;
        }
        /// <summary>
        /// 开启事务
        /// </summary>
        public IUnitOfWork BeginTransaction(IsolationLevel isolationLevel)
        {
            if (null == m_Connection)
            {
                throw new Exception("IDbConnection is null");
            }
            if (m_TransactionCount < 1 && m_Transaction == null)
            {
                m_TransactionCount = 0;
                m_Transaction = m_Connection.BeginTransaction(isolationLevel);
            }
            m_TransactionCount++;
            return this;
        }
        /// <summary>
        /// 提交事务
        /// </summary>
        public void Commit()
        {
            if (m_TransactionCount > 0)
            {
                m_TransactionCount--;
            }
            if (m_TransactionCount == 0)
            {
                m_Transaction.Commit();
                Dispose();
            }
        }
        /// <summary>
        /// 全局提交,无论嵌套多少事务,直接进行提交
        /// </summary>
        public void CommitScope()
        {
            m_Transaction.Commit();
            m_TransactionCount = 0;
            Dispose();
        }
        /// <summary>
        /// 回滚事务
        /// </summary>
        public void Rollback()
        {
            if (m_TransactionCount > 0)
            {
                m_TransactionCount--;
            }
            if (m_TransactionCount == 0)
            {
                m_Transaction.Rollback();
                Dispose();
            }
        }
        /// <summary>
        /// 全局回滚,无论嵌套多少事务,直接进行回滚
        /// </summary>
        public void RollbackScope()
        {
            m_Transaction?.Rollback();
            m_TransactionCount = 0;
            Dispose();
        }
        /// <summary>
        /// 销毁 / 关闭链接对象
        /// </summary>
        public void Dispose()
        {
            if (m_TransactionCount < 0)
            {
                if (m_Connection?.State == ConnectionState.Open)
                {
                    m_Connection.Close();
                    m_Connection.Dispose();
                    m_Connection = null;
                }
            }
            if (m_TransactionCount == 0)
            {
                m_Transaction?.Dispose();
                m_Transaction = null;
                if (m_Connection?.State == ConnectionState.Open)
                {
                    m_Connection.Close();
                    m_Connection.Dispose();
                    m_Connection = null;
                }
            }
        }
        ~UnitOfWork()
        {
            this.Dispose();
        }
    }
}
